package edu.ustb.efws.pipeline.collect.handler;

import java.time.Instant;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * 短信发送缓存
 *
 * @author TS Group
 */
public enum WarSmsCache {
    INSTANCE;

    private final ConcurrentMap<Integer, WaringSmsTime> cache;

    WarSmsCache() {
        this.cache = new ConcurrentHashMap<>();
    }

    void waring(int positionId, float score){
        WaringSmsTime time = cache.get(positionId);
        if(time == null){
            WaringSmsTime newTime = new WaringSmsTime(positionId);
            time = cache.putIfAbsent(positionId, newTime);
            time = time == null? newTime: time;
        }
        time.waringTime = Instant.now().toEpochMilli();
        time.score = score;
    }

    /**
     * 得到需要短信报警报警定编号，存在多个报警点返回最大报警分数报警点
     *
     * @param intervalMills 发送短信时间间隔
     * @param activeMills 报警有效时间段
     *
     * @return 返回发送短信pointId
     */
    public Optional<WaringSmsTime> getWaring(int intervalMills, int activeMills){
        long now = Instant.now().toEpochMilli();
        List<WaringSmsTime> times = cache.values().stream()
                .filter(e -> (e.waringTime + activeMills) > now && (e.smsTime + intervalMills) < now)
                .collect(Collectors.toList());

        if(times.isEmpty()){
            return Optional.empty();
        }

        WaringSmsTime maxScore = times.stream().max(Comparator.comparing(t -> t.score)).get();
        return Optional.of(maxScore);
    }

    /**
     * 更新发送短信时间
     */
    public void updateSmsTime(){
        long now = Instant.now().toEpochMilli();
        cache.values().forEach(e -> e.smsTime = now);
    }

    public static class WaringSmsTime {
        public final int positionId;

        WaringSmsTime(int positionId) {
            this.positionId = positionId;
        }

        //报警时间
        public volatile long waringTime;
        //短信时间
        public volatile long smsTime;
        //风险值
        public volatile Float score;
    }
}
